{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 模型文件地址\n",
    "    \n",
    "    https://github.com/PaddlePaddle/models/tree/develop/PaddleCV/image_classification\n",
    "    \n",
    "    wget http://paddle-imagenet-models-name.bj.bcebos.com/ResNet50_pretrained.tar\n",
    "    tar -xvf ResNet50_pretrained.tar\n",
    "    \n",
    "# 初始化环境\n",
    "\n",
    "    pip install opencv-python\n",
    "    pip install paddlepaddle==1.5\n",
    "    \n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from __future__ import absolute_import\n",
    "from __future__ import division\n",
    "from __future__ import print_function\n",
    "\n",
    "import os\n",
    "import cv2\n",
    "import time\n",
    "import sys\n",
    "import math\n",
    "import numpy as np\n",
    "import argparse\n",
    "import functools\n",
    "\n",
    "import paddle\n",
    "import paddle.fluid as fluid\n",
    "\n",
    "#绘图函数\n",
    "import matplotlib\n",
    "#服务器环境设置\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "\n",
    "#加载自定义文件\n",
    "from sdk.resnet import ResNet50\n",
    "from sdk.attack_pp import *\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 创建对抗样本相关的损失函数和标签并加载模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "#http://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/user_guides/howto/prepare_data/index_cn.html\n",
    "\n",
    "class_dim=1000\n",
    "image_shape=[3,224,224]\n",
    "model_name=\"resnet50\"\n",
    "use_gpu=False\n",
    "pretrained_model=\"ResNet50_pretrained\"\n",
    "TOPK=3\n",
    "\n",
    "adv_program=fluid.Program()\n",
    "\n",
    "#完成初始化\n",
    "with fluid.program_guard(adv_program):\n",
    "    input_layer = fluid.layers.data(name='image', shape=image_shape, dtype='float32')\n",
    "    #设置为可以计算梯度\n",
    "    input_layer.stop_gradient=False\n",
    "\n",
    "    # model definition\n",
    "    model = ResNet50()\n",
    "    out = model.net(input=input_layer, class_dim=class_dim)\n",
    "    out = fluid.layers.softmax(out)\n",
    "\n",
    "    place = fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace()\n",
    "    exe = fluid.Executor(place)\n",
    "    exe.run(fluid.default_startup_program())\n",
    "\n",
    "    #记载模型参数\n",
    "    fluid.io.load_persistables(exe, pretrained_model)\n",
    "    \n",
    "#设置adv_program的BN层状态\n",
    "init_prog(adv_program)      \n",
    "    \n",
    "    \n",
    "#创建测试用评估模式\n",
    "eval_program = adv_program.clone(for_test=True)\n",
    "\n",
    "#定义梯度\n",
    "with fluid.program_guard(adv_program):\n",
    "    label = fluid.layers.data(name=\"label\", shape=[1] ,dtype='int64')\n",
    "    loss = fluid.layers.cross_entropy(input=out, label=label)\n",
    "    #http://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/api_cn/backward_cn.html\n",
    "    gradients = fluid.backward.gradients(targets=loss, inputs=[input_layer])[0]\n",
    "\n",
    "  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 预测原始图片"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "error",
     "evalue": "OpenCV(4.1.0) /Users/travis/build/skvark/opencv-python/opencv/modules/imgproc/src/resize.cpp:3718: error: (-215:Assertion failed) !ssize.empty() in function 'resize'\n",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31merror\u001b[0m                                     Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-3-869775c63a67>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0mimg_path\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"mug227.png\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mimg\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mprocess_img\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimg_path\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0mfetch_list\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mout\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/Desktop/AdvBox/advsdk/sdk/attack_pp.py\u001b[0m in \u001b[0;36mprocess_img\u001b[0;34m(img_path, image_shape)\u001b[0m\n\u001b[1;32m     78\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     79\u001b[0m     \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mimread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimg_path\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 80\u001b[0;31m     \u001b[0mimg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcv2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mresize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimg\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimage_shape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mimage_shape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     81\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     82\u001b[0m     \u001b[0;31m#RBG img [224,224,3]->[3,224,224]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31merror\u001b[0m: OpenCV(4.1.0) /Users/travis/build/skvark/opencv-python/opencv/modules/imgproc/src/resize.cpp:3718: error: (-215:Assertion failed) !ssize.empty() in function 'resize'\n"
     ]
    }
   ],
   "source": [
    "img_path = \"mug227.png\"\n",
    "\n",
    "img=process_img(img_path)\n",
    "\n",
    "fetch_list = [out.name]\n",
    "\n",
    "print(img.shape)\n",
    "\n",
    "result = exe.run(eval_program,\n",
    "                 fetch_list=fetch_list,\n",
    "                 feed={ 'image':img })\n",
    "result = result[0][0]\n",
    "\n",
    "pred_label = np.argsort(result)[::-1][:TOPK]\n",
    "print(\"Test-score: {0}, class {1}\".format(result[pred_label], pred_label))\n",
    "sys.stdout.flush()\n",
    "\n",
    "\n",
    "o_img=tensor2img(img)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 调用FGSM算法 无定向攻击"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "img_path = \"mug227.png\"\n",
    "img=process_img(img_path)\n",
    "\n",
    "#生成对抗样本\n",
    "#step_size控制了扰动的大小\n",
    "adv=FGSM(adv_program=adv_program,eval_program=eval_program,gradients=gradients,o=img,\n",
    "         input_layer=input_layer,output_layer=out,step_size=64.0/256.0,epsilon=16.0/256,isTarget=False,target_label=0)\n",
    "\n",
    "    \n",
    "result = exe.run(eval_program,\n",
    "                 fetch_list=fetch_list,\n",
    "                 feed={ 'image':adv })\n",
    "result = result[0][0]\n",
    "\n",
    "pred_label = np.argsort(result)[::-1][:TOPK]\n",
    "\n",
    "print(\"Test-score: {0}, class {1}\".format(result[pred_label], pred_label))\n",
    "sys.stdout.flush()\n",
    "\n",
    "adv_img=tensor2img(adv)\n",
    "\n",
    "show_images_diff(o_img,adv_img)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 演示不同$l_{inf}$约束下FGSM无定向攻击的效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "img_path = \"mug227.png\"\n",
    "img=process_img(img_path)\n",
    "\n",
    "for epsilon in [8.0/256,16.0/256,32.0/256,64.0/256]:\n",
    "\n",
    "    #生成对抗样本\n",
    "    #step_size控制了扰动的大小\n",
    "    adv=FGSM(adv_program=adv_program,eval_program=eval_program,gradients=gradients,o=img,\n",
    "             input_layer=input_layer,output_layer=out,step_size=128.0/256.0,epsilon=epsilon,isTarget=False,target_label=0)\n",
    "\n",
    "\n",
    "    result = exe.run(eval_program,\n",
    "                     fetch_list=fetch_list,\n",
    "                     feed={ 'image':adv })\n",
    "    result = result[0][0]\n",
    "\n",
    "    pred_label = np.argsort(result)[::-1][:TOPK]\n",
    "\n",
    "    print(\"Test-score: {0}, class {1} epsilon={2}\".format(result[pred_label], pred_label,epsilon))\n",
    "    sys.stdout.flush()\n",
    "\n",
    "    adv_img=tensor2img(adv)\n",
    "\n",
    "    show_images_diff(o_img,adv_img)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 调用FGSM算法 定向攻击"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "img_path = \"mug227.png\"\n",
    "img=process_img(img_path)\n",
    "\n",
    "#生成对抗样本\n",
    "adv=FGSM(adv_program=adv_program,eval_program=eval_program,gradients=gradients,o=img,\n",
    "         input_layer=input_layer,output_layer=out,step_size=64.0/256.0,epsilon=64.0/256,isTarget=True,target_label=443)\n",
    "\n",
    "    \n",
    "result = exe.run(eval_program,\n",
    "                 fetch_list=fetch_list,\n",
    "                 feed={ 'image':adv })\n",
    "result = result[0][0]\n",
    "\n",
    "pred_label = np.argsort(result)[::-1][:TOPK]\n",
    "\n",
    "print(\"Test-score: {0}, class {1}\".format(result[pred_label], pred_label))\n",
    "sys.stdout.flush()\n",
    "\n",
    "adv_img=tensor2img(adv)\n",
    "\n",
    "#展示原始图片和对抗样本的差异\n",
    "show_images_diff(o_img,adv_img)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 演示不同$l_{inf}$约束下FGSM定向攻击的效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "img_path = \"mug227.png\"\n",
    "img=process_img(img_path)\n",
    "\n",
    "for epsilon in [8.0/256,16.0/256,32.0/256,64.0/256]:\n",
    "\n",
    "    #生成对抗样本\n",
    "    #step_size控制了扰动的大小\n",
    "    adv=FGSM(adv_program=adv_program,eval_program=eval_program,gradients=gradients,o=img,\n",
    "             input_layer=input_layer,output_layer=out,step_size=64.0/256.0,epsilon=epsilon,isTarget=True,target_label=443)\n",
    "\n",
    "\n",
    "    result = exe.run(eval_program,\n",
    "                     fetch_list=fetch_list,\n",
    "                     feed={ 'image':adv })\n",
    "    result = result[0][0]\n",
    "\n",
    "    pred_label = np.argsort(result)[::-1][:TOPK]\n",
    "\n",
    "    print(\"Test-score: {0}, class {1} epsilon={2}\".format(result[pred_label], pred_label,epsilon))\n",
    "    sys.stdout.flush()\n",
    "\n",
    "    adv_img=tensor2img(adv)\n",
    "\n",
    "    show_images_diff(o_img,adv_img)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 调用PGD算法 无定向攻击"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "img_path = \"mug227.png\"\n",
    "img=process_img(img_path)\n",
    "\n",
    "#生成对抗样本\n",
    "#step_size控制了扰动的大小\n",
    "adv=PGD(adv_program=adv_program,eval_program=eval_program,gradients=gradients,o=img,\n",
    "         input_layer=input_layer,output_layer=out,step_size=2.0/256.0,epsilon=16.0/256,iteration=20,isTarget=False,target_label=0)\n",
    "\n",
    "    \n",
    "result = exe.run(eval_program,\n",
    "                 fetch_list=fetch_list,\n",
    "                 feed={ 'image':adv })\n",
    "result = result[0][0]\n",
    "\n",
    "pred_label = np.argsort(result)[::-1][:TOPK]\n",
    "\n",
    "print(\"Test-score: {0}, class {1}\".format(result[pred_label], pred_label))\n",
    "sys.stdout.flush()\n",
    "\n",
    "adv_img=tensor2img(adv)\n",
    "\n",
    "show_images_diff(o_img,adv_img)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 调用PGD算法 定向攻击"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "img_path = \"mug227.png\"\n",
    "img=process_img(img_path)\n",
    "\n",
    "#生成对抗样本\n",
    "#step_size控制了扰动的大小\n",
    "adv=PGD(adv_program=adv_program,eval_program=eval_program,gradients=gradients,o=img,\n",
    "         input_layer=input_layer,output_layer=out,step_size=1.0/256.0,epsilon=16.0/256,iteration=20,isTarget=True,target_label=968)\n",
    "\n",
    "    \n",
    "result = exe.run(eval_program,\n",
    "                 fetch_list=fetch_list,\n",
    "                 feed={ 'image':adv })\n",
    "result = result[0][0]\n",
    "\n",
    "pred_label = np.argsort(result)[::-1][:TOPK]\n",
    "\n",
    "print(\"Test-score: {0}, class {1}\".format(result[pred_label], pred_label))\n",
    "sys.stdout.flush()\n",
    "\n",
    "adv_img=tensor2img(adv)\n",
    "\n",
    "show_images_diff(o_img,adv_img)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "py36",
   "language": "python",
   "name": "py36"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
